package com.lazyben.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lazyben.model.Message;
import com.lazyben.util.MessageUtils;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Slf4j
@Scope("prototype")
@Component
public class ClientHandler extends ChannelInboundHandlerAdapter {
    private final String clientId;

    private final MyClient myClient;

    public ClientHandler(MyClient myClient) {
        this.myClient = myClient;
        this.clientId = myClient.getClientId();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端 clientId={}，通道激活成功，向服务端注册信息...", this.clientId);
        Message msg = Message.builder()
                             .clientId(this.clientId)
                             .messageType(Message.MessageType.REGISTRY)
                             .msg("注册测试")
                             .build();

        ctx.writeAndFlush(MessageUtils.messageWrapper(msg));
//        ctx.writeAndFlush(Unpooled.copiedBuffer(new ObjectMapper().writeValueAsString(msg), CharsetUtil.UTF_8));
        log.info("注册成功，registry clientId={}， channelId={}。", this.clientId, ctx.channel().id());
//        synchronized (this.myClient) { //当通道激活后解锁队列线程，然后再发送消息
//            this.myClient.notify();
//        }

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.warn("客户端imei={}，通道断开连接", this.clientId);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = MessageUtils.parseMessage(msg);
        log.info("客户端imei={}，收到消息: {}，开始处理业务逻辑...", this.clientId, message);
        //处理业务...
//        if ("shutdown".equals(msg)) {
//            this.myClient.close();
//        }
        ctx.fireChannelRead(ctx);
    }


    /**
     * 心跳检测相关handler
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            if (e.state() == IdleState.ALL_IDLE) {
                log.info("客户端clientId={}心跳检测...", this.clientId);
                Message msg = Message.builder()
                                     .msg(String.format("客户端clientId=%s心跳检测...", this.clientId))
                                     .clientId(this.clientId)
                                     .messageType(Message.MessageType.STATE)
                                     .build();
//                ctx.writeAndFlush(Unpooled.copiedBuffer(new ObjectMapper().writeValueAsString(msg), CharsetUtil.UTF_8));
                ctx.writeAndFlush(MessageUtils.messageWrapper(msg));
            }
        }
        ctx.fireChannelRead(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("客户端clientId={}，连接异常{}", clientId, cause.getMessage(), cause);
    }
}

